/*
 *  Copyright (C) 2010 GSyC/LibreSoft, Universidad Rey Juan Carlos.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *
 *  Author : Raúl Román López <rroman@gsyc.es>
 *
 */
package com.LibreGeoSocial.App.AR;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.location.Location;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;

import com.LibreGeoSocial.Api.Audio;
import com.LibreGeoSocial.Api.GeoNode;
import com.LibreGeoSocial.Api.Note;
import com.LibreGeoSocial.Api.Photo;
import com.LibreGeoSocial.Api.User;
import com.LibreGeoSocial.App.AudioCard;
import com.LibreGeoSocial.App.NoteCard;
import com.LibreGeoSocial.App.PhotoCard;
import com.LibreGeoSocial.App.R;
import com.LibreGeoSocial.App.UserCard;
import com.LibreGeoSocial.App.AR.Overlays.CustomViews;
import com.LibreGeoSocial.App.AR.Overlays.DrawResource;
import com.LibreGeoSocial.App.Utils.LocationUtils;


public class ARGeoNode implements ARNodeDrawingIF{
	
	private static final int PHOTO = 0;
	private static final int NOTE = 1;
	private static final int USER = 2;
	private static final int AUDIO = 3;
	
	private DrawResource drawn;
	private boolean isloaded = false;
	private GeoNode geoNode;
	private float distance;
	private float azimuth = 0;
	private Point point = null;
	
	private Activity mActivity;
	private ARLayerManager layers;
	
	private Handler mHandler = new Handler(){
		@Override
		public void handleMessage(Message msg) {
			ARView activity = (ARView) mActivity;
			int num = activity.getResourcesList().indexOf(ARGeoNode.this);
			
			if(Photo.class.isInstance(geoNode)){
				Photo node = (Photo) geoNode;
				layers.refreshPhoto(num, node.getBitmapImageThumb());
			}
		}
	};
	
	private DrawResource.OnBoxChangeListener onBoxChangeListener = new DrawResource.OnBoxChangeListener() {
		
		public void onChange(int left, int top, int right, int bottom) {
			ARView activity = (ARView) mActivity;
			int num = activity.getResourcesList().indexOf(ARGeoNode.this);
			if(!layers.translateSummaryBox(num, left, top, right, bottom))
				drawn.unregisterBoxListener();
		}
	};
	
	private DrawResource.OnIconClickListener onIconClickListener = new DrawResource.OnIconClickListener() {
		public void onClick(boolean isOpen) {
			setSummaryBox(isOpen);
		}
	};
	
	public ARGeoNode(Activity activity, ARLayerManager layers, GeoNode geoNode) {
		this.mActivity = activity;
		this.geoNode = geoNode;
		this.layers = layers;
		
		point = new Point();
	}

	public GeoNode getGeoNode(){
		return geoNode;
	}
	
	public DrawResource getDrawn(){
		return drawn;
	}
	
	public Point getPoint(){
		return point;
	}
	
	public boolean isLoaded(){
		return isloaded;
	}
	
	public void setLoaded(boolean isloaded){
		this.isloaded = isloaded;
	}
	
	public void setDrawnValues(float azimuth, float abs_azimuth, float elevation, float distance){
		drawn.setValues(azimuth, elevation, distance);
		this.distance = distance;
		this.azimuth = abs_azimuth;
		
		point.set((int)(100 * Math.sin(Math.toRadians(abs_azimuth))), 
				(int)(-100 * Math.cos(Math.toRadians(abs_azimuth))));
	}
	
	public float getAzimuth(){
		return azimuth;
	}
	
	public void createDrawn(Context context, String name, Bitmap bitmap){
		this.drawn = new DrawResource(context, name, bitmap);
		this.drawn.setOnIconClickListener(onIconClickListener);
	}
	
	public void bringDrawnToFront(){
		drawn.bringToFront();
	}
	
	public void drawDistance(boolean draw){
		drawn.drawDistance(draw);
	}
	
	public void invalidateDrawn(){
		drawn.invalidate();
	}
	
	public float distanceToResource(float[] source){
		float d;
		
		Location sLocation = new Location ("gps");
		sLocation.setLatitude(source[0]);
		sLocation.setLongitude(source[1]);
		
		d = sLocation.distanceTo(geoNode.getLocation());
		
		return d;
	}
	
	public float azimuthToResource(float source[]){
		float azimuth, resource[] = new float[2];
		
		resource[0] = (float) geoNode.getLocation().getLatitude();
		resource[1] = (float) geoNode.getLocation().getLongitude();
		
		azimuth = LocationUtils.calculateResourceAzimuth(source, resource);
		
		return azimuth;
	}
	
	public float rollToResource(float distance){
		float roll;
		
		roll = LocationUtils.calculateRoll(distance, (float) geoNode.getLocation().getAltitude());
		
		return roll;
	}
	
	public void setSummaryBox(boolean setBox){
		if(!setBox){
			drawn.unregisterBoxListener();
			layers.removeSummaryBox();
			return;
		}
		
		drawn.setOnBoxChangeListener(onBoxChangeListener);
		
		String title = "";
		String description = "";
		Bitmap image = null;
		
		Thread th = null;
		
		OnClickListener clickListener = null;
		if(Photo.class.isInstance(geoNode)){
			final Photo node = (Photo) geoNode;
			title = node.getName();
			description = node.getDescription();
			
			image = BitmapFactory.decodeResource(mActivity.getResources(), R.drawable.camera);
			th = new Thread(){
				public void run(){
					node.getBitmapImageThumb();
					mHandler.sendEmptyMessage(0);
				}
			};
			clickListener = getBoxClickListener(PHOTO);
		}else if(Note.class.isInstance(geoNode)){
			Note node = (Note) geoNode;
			title = node.getTitle();
			description = node.getBody();
			
			clickListener = getBoxClickListener(NOTE);
		}else if(Audio.class.isInstance(geoNode)){
			Audio node = (Audio) geoNode;
			title = node.getName();
			description = node.getDescription();
			
			layers.drawAudioPlayer(CustomViews.audioPlayer(mActivity, (Audio)geoNode, layers));
			clickListener = getBoxClickListener(AUDIO);
		}else if(User.class.isInstance(geoNode)){
			User node = (User)geoNode;
			title = node.getUsername();
			description = node.getName();
			
			image = node.getAvatarBitmap();
			clickListener = getBoxClickListener(USER);
		}
		String dist = "";
		
		if(distance < 1000)
			dist = Float.toString(((float)((int)(distance * 100)))/100) + " m.";
		else
			dist = Float.toString(((float)((int)(distance / 10)))/100) + " Km.";
		
		ARView activity = (ARView) mActivity;
		int num = activity.getResourcesList().indexOf(this);
		layers.drawSummaryBox(num, title, description, dist, image, clickListener);
		
		if(th != null)
			th.start();
	}
	
	public OnClickListener getBoxClickListener(final int type){
		OnClickListener listener = new OnClickListener() {
			public void onClick(View v) {
				Intent intent;
				switch(type){
				case PHOTO:
					intent = new Intent(mActivity, PhotoCard.class);
					break;
				case NOTE:
					intent = new Intent(mActivity, NoteCard.class);
					break;
				case USER:
					intent = new Intent(mActivity, UserCard.class);
					break;
				case AUDIO:
					intent = new Intent(mActivity, AudioCard.class);
					break;
				default:
					return;
				}
				intent.putExtra("node", geoNode);
				mActivity.startActivity(intent);
			}
		};		
		return listener;
	}
	
	
}